/* dotEver function */
var kvAlign = {
  '_':'lodash',
  '_ws':'socket.io',
  '_wsc':'socket.io-client',
  '_wss':'socket.io-stream',
  '_krouter':'koa-router',
  '_kstatic':'koa-static'
}
const e = {
  echo : console.log.bind(console),
  spawnSync : require('child_process').spawnSync,
  path : require('path'),
  fs : require('fs'),
  setAlign(kv){
    Object.assign(kvAlign,kv);
  },
  loadModules (n,r){
      let m = Array.isArray(n) ? n : [n];
      //$ or . means path resolved with cwd
      let f = m.filter(v=>v[0] === '$' || v[0] === '.'); //if local file
      let ret = {};
      f.forEach(v=>{
          let p = v.match(/(\$)\1+/);//only header match $$~
          p = v[0] === '.' ? '\0' : p;
          let i = e.path.resolve(p ? v.replace(p[0], p[0].slice(1).replace(/(\$)/g,'../')).replace(/(\$)/g,'/') : '.' + v.replace(/(\$)/g,'/'));
          if(r){
              let j = Object.keys(require.cache).find(k=>~k.indexOf(i));
              if (j && require.cache[j].parent)
                  require.cache[j].parent.children = require.cache[j].parent.children.filter(r=>r.id !== f)
              delete require.cache[j];
          }
          ret[v] = require(i);
      });
      //if third modules
      let p = m.filter(v=>v[0] !== '$' && v[0] !== '.');
      p.forEach(v=>{
          //if from git
          let a = kvAlign[v] || v;
          let b = a.toLowerCase().startsWith('http') ? e.path.basename(a,'.git') : a;
          let f = e.path.join(e.path.resolve('./node_modules'),b);
          let i = Object.keys(require.cache).find(k=>~k.indexOf(f))
          if(r && i){
              require.cache[i].parent && (require.cache[i].parent.children = require.cache[i].parent.children.filter(r=>r.id !== i))
              delete require.cache[i];
          }
          e.fs.existsSync(f) || e.spawnSync('node',[e.path.join('./node_modules/.bin/yarn'),'add',a]);
          ret[v] = require(b);
      });
      return ret;
  },
  removeModules(n){
      let m = Array.isArray(n) ? n : [n];
      let p = m.filter(v=>v[0] !== '$' && v[0] !== '.'); 
      p.forEach(v=>{
        var a = kvAlign[v] || v;
        a = a.toLowerCase().startsWith('http') ? e.path.basename(a,'.git') : a;
        let f = e.path.join(e.path.resolve('./node_modules'),a);
        let i = Object.keys(require.cache).find(k=>~k.indexOf(f))
        i && require.cache[i].parent && (require.cache[i].parent.children = require.cache[i].parent.children.filter(r=>r.id !== i))
        delete require.cache[i];
        e.fs.existsSync(f) && e.spawnSync('node',[e.path.join('./node_modules/.bin/yarn'),'remove',a]);
      });
  }
}

module.exports = new Proxy(e,{
  get: function(o,k,c){
      try {
        return Reflect.get(o, k, c) || Reflect.apply(e.loadModules,e,[k])[k]; 
      } catch (error) {
        return require(k);
      }
  },
  set: function (o, k, v, c) { return Reflect.set(o, k, v, c);}
});
